package com.gopay.controller;

import java.math.BigDecimal;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.BobjConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.bobj.ebank.BobjB2cMessage;
import com.gopay.common.domain.bank.bobj.ebank.BobjMessage;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.util.MoneyUtil;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * 北京银行对账返回异步通知处理
 * @BobjResAnkCheckOrderB2cController.java
 * @author lilili
 * @2016-5-27 下午3:27:13  www.gopay.com.cn Inc.All rights reserved.
 */
@Controller
@Scope("prototype")
public class BobjResAnkCheckOrderB2cController {
	
	private static Logger logger = LoggerFactory.getLogger(BobjResAnkCheckOrderB2cController.class);

	@Resource(name = "bankClient")
	private BankInteractRemoteService bankClient;
    @Resource(name = "bankOrderManager")
    private BankOrderManager bankOrderManager;
    
    
    /**
	 * 跳转银行
	 * 
	 * @param HttpServletRequest
	 * @param HttpServletResponse
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/bobjB2cCheck", method = { RequestMethod.POST })
	protected void execute(HttpServletRequest request,HttpServletResponse response) {
		  logger.error("--------------- BobjResAnkCheckOrderB2cController 接收BOBJ B2C支付回应处理开始  ---------------");
	        
	        CheckOrderResult checkOrderResult = new CheckOrderResult();
			checkOrderResult.setSuccess(false);
	        /** 获取银行参数 */
	        String bankSignData = request.getParameter("bankSignData");
	        if (StringUtils.isEmpty(bankSignData)) {
	            logger.error("BobjResAnkCheckOrderB2cController接收北京银行返回报文为空，无法进行相关账务和订单处理");
	        }
	        logger.error("BobjResAnkCheckOrderB2cController接收北京银行返回报文为：" + bankSignData);
	        try {
				/** 获取银行验签后的明文 */
				Result result = this.bankClient.query(getVerifyMsg(bankSignData));
				if (result == null || !result.isSuccess()) {
					logger.error("bankClient fail.");
					if(result ==null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())){
						BankCountDownLatch.failIncrease(BankConstants.BANK_LOGO_BOBJ);
					}
					checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
					checkOrderResult.setErrMsg("系统返回对账结果为空");
				}

				/** 进行账务的后续处理 */
				BobjMessage bobjMessage = (BobjMessage) result.getModel("res");
				dealResponse(bobjMessage);

	        } catch (Exception e) {
	        	logger.error("bankClient fail.", e);
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("银行对账异常");
	        }
		
	}
	
	
	/**
     * 进行账务的后续处理
     * 
     * @param tempMap
     * @throws OrderAmtErrorException
     * @throws SQLException
     * 
     */
    // merID=000000000065, checkResult=01, orderNum=2012032700860928,
    // CheckDate=20120327, orderAmt=1
    // 0:无缴费记录,01:缴费成功,02:无成功缴费记录,03:完全退费成功,04:部分退回成功
    private void dealResponse(BobjMessage bobjMessage) {
        /** settleDate取当前时间 */
        CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
        try {

			if (bobjMessage == null) {
				// 查询订单为空
				checkOrderResult
						.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("银行返回对账结果为空");
			}
			if (BobjConstants.NO_ORDER.equals(bobjMessage.getCheckResult())) {
				checkOrderResult
				.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
		        checkOrderResult.setErrMsg("银行返回交易无此订单");
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易无此订单");
			} else if (BobjConstants.ORDER_SUCCESS.equals(bobjMessage.getCheckResult())) {
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易成功");
				checkOrderResult.setErrMsg("银行返回交易成功");
				checkOrderResult.setSuccess(true);
				InAccInfo accInfo = new InAccInfo();
				accInfo.setOrderId(bobjMessage.getOrderNum());
				accInfo.setAmount(new BigDecimal(MoneyUtil.formatAmt(bobjMessage.getOrderAmt())));
				accInfo.setRetCode("00");
				accInfo.setCardType(BankCardType.Unknown.toString());
				checkOrderResult.setAccInfo(accInfo);
			} else if (BobjConstants.NO_SUCCESS_ORDER.equals(bobjMessage.getCheckResult())) {
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易无成功缴费记录");
		        checkOrderResult.setErrMsg("银行返回交易无成功缴费记录");
		        checkOrderResult
				.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
		   
			} else if (BobjConstants.ORDER_RET_ALL.equals(bobjMessage.getCheckResult())) {
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易完全退费成功");
				checkOrderResult.setErrMsg("银行返回交易完全退费成功");
			
			} else if (BobjConstants.ORDER_RET_PART.equals(bobjMessage.getCheckResult())) {
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易部分退回成功");
				checkOrderResult.setErrMsg("银行返回交易部分退费成功");
			
			} else {
				logger.error("北京银行B2C订单" + bobjMessage.getOrderNum() + "的交易发生未明情况");
				checkOrderResult.setErrMsg("银行返回交易未明情况");
				
			}
			
            if (checkOrderResult.isSuccess()) {
                logger.info("bank orderid: " + bobjMessage.getOrderNum() + ",银行对账成功");
                BankOrder bankOrder = null;
                bankOrder = bankOrderManager.getByGopayOutOrderId(bobjMessage.getOrderNum());
                String amt = checkOrderResult.getAccInfo().getAmount().toString(); // 银行返回交易金额
                if (bankOrder.getSendBankAmt() != null
                        && bankOrder.getSendBankAmt().compareTo(new BigDecimal(amt)) != 0) {
                    // 银行返回金额与平台上送金额不符
                    bankOrderManager.updateAmountError(bankOrder);
                    logger.error("bank orderid: " + bankOrder.getOrderId() + "金额校验不符");
                    return;
                }
                
                // 对单成功
                bankOrderManager.updateSuccess(bankOrder, BankOrderStatus.AUTO_CHECK_SUCCESS);
                checkOrderResult.setSuccess(true);
                logger.info("bank orderid: " + bankOrder.getOrderId() + ",更新银行订单状态成功");
                bankOrderManager.inAcct(checkOrderResult);
            }
		} catch (Exception e) {
			logger.error("bankClient fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行对账异常");
		}
    }

    private BobjMessage getVerifyMsg(String bankSignData) {
        BobjB2cMessage bobjMessage = new BobjB2cMessage();
        bobjMessage.setSpecial("2");
        bobjMessage.setSignMessage(bankSignData);
        bobjMessage.setBank(BankConstants.BANK_LOGO_BOBJ);
        bobjMessage.setBankBusProd(BisBankBusinessProd._00);
        bobjMessage.setBankIntrChann(BisBankInterfaceChannel._00);
        return bobjMessage;
    }
}
